<?php

/**
 * Project form base class.
 *
 * @package    form
 * @version    SVN: $Id: sfDoctrineFormBaseTemplate.php 6174 2007-11-27 06:22:40Z fabien $
 */
abstract class BaseFormDoctrine extends sfFormDoctrine
{
	 public $steps;
	 public $objectDef;
	 public $hiddenFields;
	 public $scheduledForDeletion;
	 
	 public function setup(){
		
	 	$this->scheduledForDeletion = array();
		$this->hiddenFields = array();
  		if(isset($_SESSION['extraAttributes']))
  			unset($_SESSION['extraAttributes']);
  		$this->widgetSchema->getFormFormatter()->setTranslationCatalogue('forms');
  		
	  	$class = $this->getObject()->getTable()->getClassnameToReturn();
	  	$objDef = new objectDef($class);
		$this->objectDef = $objDef;		
		if($objDef->classExists)
		{
		 	$i18N = sfContext::getInstance()->getI18N();
			$aide = sfConfig::get('app_form_aideRapide', false);
			if($aide){
				$funcs = new erdfFuncs;
				$idCategorie = 0;
				$categories = Doctrine::getTable('categoriedemande')
		      		->createQuery('a')
		      		->where("a.xtable = '".$class."'")
		        ->execute();
		        foreach($categories as $categorie){
		        	$idCategorie = $categorie->id;
		        }
				$funcs->setHelp($idCategorie, '');
				unset($funcs);
				unset($categories);
			}
			unset($aide);
			if($objDef){
				if($objDef->timeStampable){
					if(isset($this['created_at']))
						unset($this['created_at']);
					if(isset($this['updated_at']))
						unset($this['updated_at']);
				}
				$this->steps = array();
				foreach($objDef->attributes as $fieldName => $att){
					if($att['type']!='List' and $att['type']!='function'){
						$this->setMyWidget($fieldName, '', null, null, $objDef);
					}
					if($att['type']=='BOList' and sfConfig::get('app_autoforms_newitems', true))
					{
							unset($this[$fieldName.'_id']);
						    //An empty form will act as a container for all items
						    $wrapperForm = new SfForm();
						    $count = 0;
						    $items = $this->getObject()->$fieldName;
						    foreach ($items as $keyd=>$item) {
						    	$itemclass = get_class($item);
						    	$itemFormClass = $itemclass . 'Form';
						      	$itemForm = new $itemFormClass($item);
						      	$itemForm->unsetBoListFields();
						      	//Embedding each form in the container
						      	$wrapperForm->embedForm($count, $itemForm);
						      	$count ++;
						    }
						  	//Embedding the container in the main form
						    $this->embedForm($fieldName, $wrapperForm);		
							//Array to set eventual object delete
						    $this->scheduledForDeletion[$fieldName]= array();
					}
				}
			}
			if($objDef->hasStatus){
				$options = array($i18N->__('Active'),$i18N->__('Suspended'),$i18N->__('Deleted'),);
				$objDef->attributes['activeStatus']['label'] = $i18N->__('Active Status');
				$this->setMyWidget('activeStatus', '', $options, 0, $objDef);
			}
			$formaterName = sfConfig::get('app_form_formatterName','app');
			$this->getWidgetSchema()->setFormFormatterName($formaterName);
	
			if($objDef){
				if($objDef->idIsGuid){
					$util = new Util();
					$this->setDefault('id',$util->createGUID());
					$this->validatorSchema['id'] = new sfValidatorString(array('max_length' => 36, 'required' => true));
					unset($util);
				}
			}
			
			//Search for "owner_id" widgets
			//The have to be unsetted to let pere-child forms to work.
			//Util::sendDebug('Start!:', 2);
			if(sfConfig::get('app_autoforms_newitems', true))
			{
				$fieldName = $this->getOwnerField();
				if($fieldName)
				{
					unset($this[$fieldName]);
				}
			}
			$this->extraTemplates = array();
			if($objDef){
				if($objDef->formExtraTemplate!=''){
					$this->extraTemplates[]=$objDef->formExtraTemplate;
				}
			}
			$sf_user = sfContext::getInstance()->getUser();
			/*Existint defaults?*/
			if($sf_user->hasAttribute('defaults_'.get_class($this))){
				$defaults = $sf_user->getAttribute('defaults_'.get_class($this));
				$this->setDefaults($defaults);
				$sf_user->getAttributeHolder()->remove('defaults_'.get_class($this), 'namespace');
			}
			
				  		
			unset($obj);
			unset($class);  	  	
	  		unset($i18N);
	  		unset($formaterName);
		}
	 }
    
  
	 public function setMyWidget($fieldName, $filter = '', $options = null, $default = null, $objDef = null){
 		$obj = $this->getObject();
  		$objTable = $obj->getTable();
		$class = $objTable->getClassnameToReturn();
		$widgetsToUnset = array();
 		$i18N = sfContext::getInstance()->getI18N();
 		$util = new Util();
 		if(is_null($objDef)){
 			$objDef = new objectDef($class);
 		}
		$charset = $objDef->charset;
  		
 		$doctrineColumns = $objTable->getColumns();
		
		if($objDef)
		{
				$att = $objDef->attributes[$fieldName];
		}
		else
		{
			
		}
		
		if($att['type']=='BO' or $att['type']=='BOList')
	   	{
				$fieldName = $fieldName.'_id';	
		}
		
		$doctColDef =	$util->getDoctrineDef($class, $fieldName, $doctrineColumns);
		$typeDoct =	$doctColDef['type'];
		$notnull = false;
		
		if($att['notnull']){
		 	$notnull = true;
		}else{
			if($att['type']!= 'List' and $att['type']!= 'BOList')
			{
				$fieldName2 = $fieldName;
				if($att['type']=='CheckboxList')
				{
					$fieldName2 = $fieldName.'_list';	
				}			
   		 		$this->getValidator($fieldName2)->setOption('required', false);
			}
		}
		unset($doctrineColumns);
		
	 	/****
		 * WIDGET CREATION DEPENDING ON DATATYPE
		 * *****************/
	 	if(($att['type']=='BO' or $typeDoct=='BO') and $fieldName!='id' and $att['type']!= 'List'){
	 		
	 		if($att['relatedClass']!=''){
					$relatedClass = $att['relatedClass'];
			}else{	
					$relatedClass = $doctColDef['relatedClass'];
			}
	 		if($relatedClass!=''){	
	 			if(is_null($options)){
	 				$relatedObjDef = new objectDef($relatedClass);
					$relatedTable = Doctrine::getTable($relatedClass);
					$id = $relatedTable->getIdentifier();	
					if($relatedObjDef->classExists){
							$descriptor = $relatedObjDef->descriptor;
					}else{
							$descriptor='';
							$searchBar = new searchBar();
							$descArray = $searchBar->descArray; 
							$columns = $relatedTable->getFieldNames();
							foreach($columns as $key){ // => $attDef
								if(in_array($key,$descArray)){
									$descriptor = $key;	
								}
							}
							if($descriptor=='') {
								$descriptor = $id;
							}		
							unset($searchBar);
							unset($descArray);
							unset($columns);
					}
					
					$addEmpty = true;
					$isnumeric = false;
					$options = array();
					$q=Doctrine_Query::create()
		    			->select('a.'.$id.' as id, a.'.$descriptor.'  as name')
					    ->from($relatedClass.' a') 
					    ->orderBy('a.'.$descriptor);
			 		if(!$filter==''){
			 			$q->andWhere('a.'.$filter);
			 		}
			 		if($relatedObjDef->hasStatus){
			 			$q->andWhere('a.activeStatus = 0');
			 		}
			 		$this->widgetSchema[$fieldName] = new sfWidgetFormDoctrineChoice2(
		 							array('model' => $relatedClass,
		 							//'method'=> 'get'.$descriptor,
		 							'query' => $q,
		 							'add_empty' => sfContext::getInstance()->getI18N()->__('Please select a value...')));

				}else{
					$this->widgetSchema[$fieldName] = new sfWidgetFormChoice(
													array('multiple' => false,
									  					  'expanded' => false,
									  					  'choices'  => $options,));
				}		
	 		}
		}	
	 
		if($att['type']=='secret'){
			 $this->widgetSchema[$fieldName] = new sfWidgetFormInputPassword();
		}
		elseif($att['type']=='date' or $att['type']=='timestamp'){
			$dateOptions = array();
			$widgetDateName = sfConfig::get('app_form_datewidgetclass', 'sfWidgetFormDateJS');//'sfWidgetFormDateJQueryUI'; //
			if($widgetDateName=='sfWidgetFormDateJQueryUI'){
				$dateOptions['theme']='/css/app/ui-lightness/jquery-ui.css';
				if($att['type']=='timestamp'){
					$dateOptions['istimestamp'] = true;	
				}
			}
		    $this->widgetSchema[$fieldName] = new $widgetDateName($dateOptions);
		}elseif($att['type']=='image'){
		     $this->widgetSchema[$fieldName] = new sfWidgetFormInputFile();
		     $webdir = sfConfig::get('sf_web_dir');
		     $this->validatorSchema[$fieldName] = new sfValidatorFile(array('required' => $notnull,
		      'path' => $webdir.DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR.$objDef->filesPathName,
		      'mime_types' => 'web_images',
		     ));
		}elseif($att['type']=='file'){
			/* $path = sfConfig::get('sf_'.$objDef->filesPathName.'_dir','sf_upload_dir');
		     $this->widgetSchema[$fieldName] = new sfWidgetFormInputFile();
		    
		     $this->validatorSchema[$fieldName] = new sfValidatorFile(array('required' => $notnull,
		     	'path' => $path//$dirName
		     ));*/
			 if($objDef->filesPathName==''){
			 	$dirName = 'sf_upload_dir';
			 }else{
			 	$dirName = 'sf_'.$objDef->filesPathName.'_dir';
			 }
		     $path = sfConfig::get($dirName);
		     $this->widgetSchema[$fieldName] = new sfWidgetFormInputFile();
		     if($this->getObject()->$fieldName!=''){
		     	$notnull = false;
		     }
		     $this->validatorSchema[$fieldName] = new sfValidatorFile(array('required' => $notnull,
		     	'path' => $path
		     ));
		}elseif(($att['type']=='integer' or $att['type']=='string' or $att['type']=='decimal') and !is_null($options) and ($typeDoct!='BO')){
			$this->widgetSchema[$fieldName] = new sfWidgetFormChoice(
											array('multiple' => false,
							  					  'expanded' => false,
							  					  'choices'  => $options,));			
		}elseif($att['type']=='array'){
				if($att['relatedClass']!=''){
						$relatedClass = $att['relatedClass'];
				}else{	
						$relatedClass = $doctColDef['relatedClass'];
				}
		 		if($relatedClass!=''){	
		 			if(is_null($options)){
		 				$relatedObjDef = new objectDef($relatedClass);
						$relatedTable = Doctrine::getTable($relatedClass);
						$id = $relatedTable->getIdentifier();	
						if($relatedObjDef->classExists){
								//$descriptor = ''; 
							$descriptor = $relatedObjDef->descriptor;
						}
						if($descriptor=='') $descriptor = 'id' ;
						//$filter = '';
						$addEmpty = true;
						$isnumeric = false;
						$options = array();
		 				if($relatedObjDef->hasStatus){
			 				$filter = 'activestatus = 0';
			 			}
			 			$options = $util->getOptions($relatedClass, $id, $descriptor, $filter, $addEmpty, $isnumeric);
			 			$this->widgetSchema[$fieldName] = new sfWidgetFormChoice(
															array('multiple' => false,
											  					  'expanded' => false,
											  					  'choices'  => $options,
															));
					}
					if(isset($options[0])){
						$options[0] = $i18N->__('You can select multiple choices (Ctrl + clic)');
					}
					if(isset($options[''])){
						$options[''] = $i18N->__('You can select multiple choices (Ctrl + clic)');
					}
					
			 	}elseif($att['enumValues']!=''){
			 		$options = $util->getArrayFromStr($util->stripAccents2($att['enumValues']),';',$i18N->__('You can select multiple choices (Ctrl + clic)'),'=>');
					
			 	}
				$this->widgetSchema[$fieldName] = new sfWidgetFormChoice(
				array('choices'=>$options, 'multiple' => true,'expanded' => false));				
		}elseif($att['type'] == 'enum'){
			if(!isset($options)){
				$options = $util->getArrayFromStr($util->stripAccents2($att['enumValues']),';',true,'=>');
			}
			$this->widgetSchema[$fieldName] = new sfWidgetFormChoice(
			array('choices'=>$options, 'multiple' => false,'expanded' => false));
		}elseif($att['type'] == 'CheckboxList'){
			$fieldName.='_list';
			if($att['relatedClass']!=''){
					$relatedClass = $att['relatedClass'];
			}else{	
					$relatedClass = $doctColDef['relatedClass'];
			}
	 		if($relatedClass!=''){	
	 			if(is_null($options)){
	 				$relatedObjDef = new objectDef($relatedClass);
					$relatedTable = Doctrine::getTable($relatedClass);
					$id = $relatedTable->getIdentifier();	
					if($relatedObjDef->classExists){
							//$descriptor = ''; 
							$descriptor = $relatedObjDef->descriptor;
					}
					if($descriptor=='') $descriptor = 'id' ;
					//$filter = '';
					$addEmpty = false;
					$isnumeric = false;
					$options = array();
					
					$options = $util->getOptions($relatedClass, $id, $descriptor, $filter, $addEmpty, $isnumeric);
				}
	 		}
	 		$this->widgetSchema[$fieldName] = new sfWidgetFormSelectCheckbox(
			array('choices'=>$options, 'formatter'=>array($this, 'radioListFormatter')));	//, 'multiple' => true,'expanded' => true)
			//$this->validatorSchema[$fieldName] =  new sfValidatorString(array('required' => false));
			$this->validatorSchema[$fieldName] = new sfValidatorDoctrineChoice(array('multiple' => true, 'model' => $relatedClass, 'required' => false));
			//new sfValidatorDoctrineChoice(array('multiple' => true, 'model' => 'sfGuardPermission', 'required' => false)),
			
			
		}elseif($att['type']=='BOList'){
			if(!sfConfig::get('app_autoforms_newitems', true))
			{
		     $this->widgetSchema[$fieldName] = new sfWidgetFormInputHidden();
		     $this->validatorSchema[$fieldName] = new sfValidatorString(array('required' => false));
			}
		}elseif($att['type']=='tinyMCE'){
		     $this->widgetSchema[$fieldName] = new sfWidgetFormTextareaTinyMCE(array('width'=>'800', 'height'=>'300'));
		}

		/*******************
		 * LABELS
		 * *****************/
		
		if($charset=='utf8'){
		 	if($att['label']==''){
		 		$label = $i18N->__($fieldName,null,'forms');
		 	}else{
		 		$label = $i18N->__($att['label'],null,'forms');
		 	}
		}else{
		 	//$label = utf8_decode($i18N->__($att['label']),null,'forms');
		 	$label = $i18N->__($att['label'],null,'forms');
		}
		if($notnull){
		 	 $label .= ' *';
		}
		$this->offsetGet($fieldName)->getWidget()->setLabel($label);
		unset($label);
		
		/****
		 * HELPS
		 * *****************/
		if($charset=='utf8'){
		 	if($att['help']==''){$help = ' ';}else{ $help = $i18N->__($att['help'],null,'forms');};
		}else{
		 	if($att['help']==''){$help = ' ';}else{ $help = utf8_decode($i18N->__($att['help'],null,'forms'));};
		}
		if($att['type']=='date'){
			if($att['help']==''){
				$help = $i18N->__('Date with format %format%', array('%format%'=>'DD/MM/YYYY'));
			}
		}
	 	if($att['type']=='timestamp'){
			if($att['help']==''){
				$help = $i18N->__('Date-Time with format %format%', array('%format%'=>'DD/MM/YYYY hh:mm:ss'));
			}
		}
  		if($att['type']=='file')
  		{   
  			$max = ini_get('upload_max_filesize');
  			//$help .= $i18N->__('La taille maximale du ficher est %max% octets.');
			$help .= $i18N->__('(Maximum file size is %max_size% bytes)',array('%max_size%'=>$max));
		}			
		$this->getWidgetSchema()->setHelp($fieldName, $help);
		
		/****
		 * HTML ATTRIBUTES
		 * (Including tmt validator !)
		 * *****************/
		$concatError = '';
		$attributes['tmt:message'] = ''; 
		if($att['show'] and $att['type']!= 'List')
		{
			
			$attributes=array('class' => 'text');
			
			if(($att['type']=='BO'or$typeDoct=='BO') and $fieldName<>'id' and $att['type']!='array')
			{
				$attributes['class'] = 'combobox';
			}
			elseif(($att['type']=='integer' or $att['type']=='string' or $att['type']=='decimal') and !is_null($options))
			{
				$attributes['class'] = 'combobox';		
			}
			elseif($att['type']=='integer')
			{
				$attributes['tmt:pattern'] = "integer";
				if(!isset($attributes['tmt:message'])) 	$attributes['tmt:message'] = '';
				$attributes['tmt:message'] .= $concatError . $i18N->__("Incorrect Integer");
				$concatError = ' / ';
			}
			elseif($att['type']=='decimal')
			{
				$attributes['tmt:pattern'] = "number";
				if(!isset($attributes['tmt:message'])) 	$attributes['tmt:message'] = '';
				$attributes['tmt:message'] .= $concatError . $i18N->__("Incorrect Float");
				$concatError = ' / ';
			}
			elseif($att['type']=='date' or $att['type']=='timestamp')
			{
				$attributes['class'] = 'date';
				if($att['type']=='timestamp'){
					$attributes['tmt:pattern'] = "timestamp";
				}else{
					$attributes['tmt:datepattern'] = "DD/MM/YYYY";
				}
				if(!isset($attributes['tmt:message'])) 	$attributes['tmt:message'] = '';
				$attributes['tmt:message'] .= $concatError .  $i18N->__("Incorrect date format"); //Formato de fecha incorrecto "Le format de la date est incorrecte";
				$concatError = ' / ';
			}
			elseif($att['type']=='blob')
			{
				$attributes['class'] = 'textarea';
			}
			elseif($att['type']=='tinyMCE')
			{
				$attributes['class'] = 'mceEditor';
			}
			elseif($att['type']=='boolean')
			{
				$attributes['class'] = 'radioCheck';
			}
			elseif($att['type']=='array')
			{
				$attributes['class'] = 'array';
				$attributes['tmt:invalidindex'] = '0';
			}elseif($att['type']=='CheckboxList'){
				$attributes['class'] = 'CheckboxList';
			}elseif($att['type'] == 'enum'){
				$attributes['class'] = 'combobox';		
			}
			
			if($notnull)
			{	
				if($att['type']!='CheckboxList'){
					$attributes['class'] = $attributes['class'].' required';
				}
				$attributes['tmt:required'] = "true";
				$attributes['tmt:errorclass']=  "invalid";
				if(!isset($attributes['tmt:message']))
					$attributes['tmt:message'] = '';
					
				$attributes['tmt:message'] .= $i18N->__("Required Attribute"); //"Atributo Obligatorio"; "Champ obligatoire";
				$concatError = ' / ';			
				if($att['type']=='BO' or $typeDoct=='BO')
				{
					$attributes['tmt:invalidindex'] = "0";
				}
				if(($att['type']=='integer' or $att['type']=='string' or $att['type']=='float') and !is_null($options))
				{
					$attributes['tmt:invalidindex'] = "0";
				}
				if($att['type'] == 'enum'){
					$attributes['tmt:invalidindex'] = "0";
				}				
				if($att['type']=='CheckboxList'){
					$attributes['tmt:minchecked'] = '1';
					$attributes['tmt:message'] .= $i18N->__("You must choose at least one option"); //"Atributo Obligatorio"; "Champ obligatoire";
				}
				
			}
			if($att['readOnly'])
			{
				$this->setReadOnly($fieldName);
				$attributes['disabled'] = "true";
			 }
			 if($att['size']!="0" and $att['size']!=''){
			 	    $attributes['maxlength'] = $att['size'];
			 }
			 
			 $attributes['class'] = $attributes['class'].' form';
			 
			 
			 if( $att['ajaxFunction']!='')
			 {
			 	if($att['type']=='CheckboxList'){
			 		//$attributes['onChange'] = $att['ajaxFunction'];
			 		$this->getWidget($fieldName)->addOption('onchange', $att['ajaxFunction']);	 		
			 	}else{
				 	$attributes['onChange'] = $att['ajaxFunction'];
				 	if($att['type']=='boolean') // or $att['type']=='CheckboxList' 
				 	{
				 		$attributes['onclick'] = 'this.blur();'; //Compatiblidad ie7
				 	}
			 	}
			 } 
			 if($att['pattern']!=''){
			 	$attributes["tmt:pattern"] = $att['pattern'] ;
			 }
		 
			 if($att['errorMessage']!=''){
				if(!isset($attributes['tmt:message'])) $attributes['tmt:message'] = '';
			 	if($charset=='utf8'){
			 		$attributes['tmt:message'] .= $concatError.$att['errorMessage'];
			 	}else{
			 		$attributes['tmt:message'] .= $concatError.utf8_decode($att['errorMessage']);
			 	}
			 	$concatError = ' / ';
			 }				 
			 if(isset($attributes['tmt:message'])){
			 	if($attributes['tmt:message']=='') unset($attributes['tmt:message']);
			 }
			
			 $this->offsetGet($fieldName)->getWidget()->setAttributes($attributes);
			 if(isset($att['step'])){
				 if($att['step']!=''){
					if(in_array($att['step'],array_keys($this->steps))){
						$this->steps[$att['step']][] = $fieldName;
					}else{
						$this->steps[$att['step']] = array($fieldName);
					}
				 }				 
			 }
		 }else{
		 	if($fieldName=='id'){
		 		if(sfConfig::get('app_general_idAreGuids', false)){
		 			$this->widgetSchema[$fieldName] = new sfWidgetFormInputHidden();
		 		}	
		 	}else{
		 		$this->widgetSchema[$fieldName] = new sfWidgetFormInputHidden();
		 	}
		}
		if(is_null($default))
		{
	    	if($att['show'])
	    	{
	    		$dateformat='d/m/Y'; 	
	    	}
	    	else 
	    	{
	    		$dateformat='Y-m-d'; 	
	    	}
	    	$default = Util::processDefaultExpression($att['default'], $att['type'], $dateformat);
			$this->setDefault($fieldName, $default);
		}else{
			if($att['type']=='date'  or $att['type']=='timestamp'){
				$dateArray=explode('/',$default);
				if(count($dateArray)==3){
					$xdate = mktime(0,0,0,$dateArray[1],$dateArray[0],$dateArray[2]);
				}else{
					$dateArray=explode('-',$default);
					$xdate = mktime(0,0,0,$dateArray[1],$dateArray[2],$dateArray[0]);
					unset($dateArray);
				}
				if($att['readOnly']){
					$format = "Y-m-d";
				}else{
					$format = "d/m/Y";
				}	
				$this->setDefault($fieldName, date($format,$xdate));
				unset($xdate);
			}else{
				$this->setDefault($fieldName, $default);
			} 
		}
		
		foreach($widgetsToUnset as $fieldName){
			unset($this[$fieldName]);
		}
		unset($options);
		unset($attributes);
		unset($att);
		unset($objectDef);
		unset($util);
		unset($obj);
  		unset($objTable);
		unset($class);  	
		unset($doctColDef);
		unset($util);
		unset($doctrineColumns);
		unset($attributes);			
	 }	 
 	
   
   public function hideWidget($fieldName){
   	if(isset($this->objectDef->attributes[$fieldName])){
   		$this->hiddenFields[] = $fieldName;
   		$att = $this->objectDef->attributes[$fieldName];
   		if($att['type']!='BOList' and $att['type']!='List' and $att['type']!='function'){
   			if($att['type']=='BO') $fieldName .= '_id';
	   		$this->widgetSchema[$fieldName] = new sfWidgetFormInputHidden();
	   		$this->widgetSchema[$fieldName]->setLabel(' ');
   		}
   	}
   }
   
   
   public function setReadOnly($fieldName){
   	if(isset($this->objectDef->attributes[$fieldName])){
   		$att = $this->objectDef->attributes[$fieldName];
	   	if($att['type']!='BOList' and $att['type']!='List' and $att['type']!='function'){
	   			if($att['type']=='BO') $fieldName .= '_id';
	   	}
	   	if($att['type']=='date'  or $att['type']=='timestamp'){
	   		$this->getWidget($fieldName)->setOption('read_only', true);
	   	}
	   	$this->getWidget($fieldName)->setAttribute('disabled', 'true');
   	}

   }
   
   public function unsetReadOnly($fieldName){
   	if(isset($this->objectDef->attributes[$fieldName])){
   		$att = $this->objectDef->attributes[$fieldName];
   		if($att['type']!='BOList' and $att['type']!='List' and $att['type']!='function'){
	   			if($att['type']=='BO') $fieldName .= '_id';
	   	}
	   	$attributes = $this->getWidget($fieldName)->getAttributes();
	   	unset($attributes['disabled']);
   		$this->getWidget($fieldName)->setAttributes($attributes);
   	}
   }
   
   public function setMandatory($fieldName){ 
   	   $i18N = sfContext::getInstance()->getI18N();  
	   if(isset($this->objectDef->attributes[$fieldName])){
	   		$att = $this->objectDef->attributes[$fieldName];
		   	if($att['type']!='BOList' and $att['type']!='List' and $att['type']!='function'){
		   			if($att['type']=='BO') $fieldName .= '_id';
		   	}
			$class = $this->getWidget($fieldName)->getAttribute('class');
	   		if($att['type']!='CheckboxList'){
				$class .= ' required';
			}
			$this->getWidget($fieldName)->setAttribute('class', $class);
			$this->getWidget($fieldName)->setAttribute('tmt:errorclass', 'invalid');
			$message  = $this->getWidget($fieldName)->getAttribute('tmt:message');
			$concatError = '';
			if($message) $concatError = ' / ';
			if($att['type']=='CheckboxList'){
				$message .= $i18N->__("You must choose at least one option"); //"Atributo Obligatorio"; "Champ obligatoire";
			}else{
				$message .= $concatError . $i18N->__("Required Attribute");
			}
			$this->getWidget($fieldName)->setAttribute('tmt:message', $message);
			
			if($att['type']=='BO' or $att['type'] == 'enum')
			{
				$this->getWidget($fieldName)->setAttribute('tmt:invalidindex', '0');
			}elseif($att['type']=='CheckboxList'){
				$this->getWidget($fieldName)->setAttribute('tmt:minchecked', '1');
			}else{
				$this->getWidget($fieldName)->setAttribute('tmt-required', 'true');
			}
			$this->getValidator($fieldName)->setOption('required', true);
			
	   }
   }
   
   public function setNonMandatory($fieldName){   
	   if(isset($this->objectDef->attributes[$fieldName])){
	   		$att = $this->objectDef->attributes[$fieldName];
		   	if($att['type']!='BOList' and $att['type']!='List' and $att['type']!='function'){
		   			if($att['type']=='BO') $fieldName .= '_id';
		   	}
			
		   	$class = $this->getWidget($fieldName)->getAttribute('class');
			$class = str_replace('required', '', $class);
			$this->getWidget($fieldName)->setAttribute('class', $class);
			
			$attributes = $this->getWidget($fieldName)->getAttributes();
	   		if($att['type']=='BO' or $att['type'] == 'enum')
			{
				unset($attributes['tmt:invalidindex']);
			}
			elseif($att['type']=='CheckboxList')
			{
				unset($attributes['tmt:minchecked']);
			}
			else
			{
				unset($attributes['tmt:required']);
			}
			$this->getWidget($fieldName)->setAttributes($attributes);
			$this->getValidator($fieldName)->setOption('required', false);
	   }
   }   
   
   public function afterCommit($self){
   	
   }
    
   public function extendedSetup(){
 			// Affiche l'aide rapide

   }
 
	public function radioListFormatter($widget, $inputs)
	{
	    $rows = array();
	    foreach ($inputs as $i => $input)
	    {
	      $rows[] = $widget->renderContentTag(
	        	  'li', 
	                  $input['input'].$widget->getOption('label_separator').$input['label'],
	                  array('style'=>'list-style-type:none', 'id'=>'li_'.$i, 'onchange'=>$widget->getOption('onchange')) //Seule réelle modification par rapport à la fonction définie de base dans la classe sfWidgetFormSelectCheckbox
	                );
	    }
	    return $widget->renderContentTag('ul', ''.implode($widget->getOption('separator'), $rows), array('class' => 'radio_list'));
	}
 
  public function updateDefaultsFromObject()
  {
    parent::updateDefaultsFromObject();
    if(!$this->getObject()->isNew()){
    	$class = get_class($this->getObject());
    	$objDef = new objectDef($class);
    	if($objDef->hasAttach){
		  	$qattach = Doctrine_Query::create()
				->select('d.*')
				->from('attachment d');
	
			if(is_numeric($this->getObject()->id)){
				$qattach->where('d.owner_id = '.$this->getObject()->id);
			}else{
				$qattach->where('d.owner_id = \''.$this->getObject()->id.'\'');
			}			
			
			$qattach->addWhere('d.ownerclass = \''.$class.'\'');
			/*No Hydrate ARRAY because we need the objects!
			$qattach->setHydrationMode(Doctrine_Core::HYDRATE_ARRAY);
			*/ 
			$attachs = $qattach->execute(); 
			$user =  sfContext::getInstance()->getUser();
			$files = $user->getAttribute('filesToUpload');
			if(!isset($files))	$files = array();
			foreach($attachs as $attachment){
				$ext = pathinfo($attachment->file, PATHINFO_EXTENSION);
				$filename = $attachment->filename.'.'.$ext;
				if(!in_array($filename,$files)){
					$files[$filename] = $attachment;
				}	
			}
			if(count($files)>0){
				$user->setAttribute('filesToUpload',$files);
			}
    	}
    }
  }

  public function addItem($fieldname, $num){
	  $classname = $this->objectDef->attributes[$fieldname]['relatedClass']; 
  	  $item = new $classname();
	  $relationName = $this->getOwnerRelationName($classname, $this->objectDef->className);
	  if($relationName=='')
	  {
	  	throw new sfException('Onwer relatioship not found', '500');
	  }
	  $item->$relationName = $this->getObject(); 
	  $formClass = $classname . 'Form';
	  $form = new $formClass($item);

	  //Embedding the new form in the container
	  $this->embeddedForms[$fieldname]->embedForm($num, $form);
	  //Re-embedding the container
	  $this->embedForm($fieldname, $this->embeddedForms[$fieldname]);
  }
  
  
  private function getOwnerRelationName($classname, $ownerClassname)
  {
	$relations = Doctrine::getTable($classname)->getRelations();
	$relatedObjDef = null;
	$relationName = '';
    foreach ($relations as $name => $relation) 
    {
       	if($relation->getType() == 0)
       	{
			$relatedClass = $relation->getClass();
			if($relatedClass == $ownerClassname)
			{
    			return $name;
			}
    	}
	}
	return '';
	
  }
  

  /* Returns field name that makes the link with the parent table in a pere-child relationship.
   * The function searchs all one to one relations of the current object, 
   * and for each related object, searchs a one to many relation reflecting to him
   * 
   * @param string $att_type 	|whether to search for List or BoList (default BOList) 
   * 
   * return string
   * 
   * */
  public function getOwnerField($att_type = 'BOList')
  {
  		$ownerData = Util::getOwnerFieldAndClass($this->getObject(), $att_type);	
  		
  		if($ownerData && $ownerData['ownerField'])
  		{
  			return $ownerData['ownerField'];
  		}
  		else 
  		{
  			return false;
  		}
  }

  public function bind(array $taintedValues = null, array $taintedFiles = null)
  {
	
  	if(sfConfig::get('app_autoforms_newitems', true))
  	{
		foreach($this->objectDef->attributes as $fieldName => $att)
		{
			if($att['type']=='BOList')
			{
			  if(isset($taintedValues[$fieldName]))
			  {
			  	  // add new items if they exist
				  foreach($taintedValues[$fieldName] as $key=>$newItem)
				  {
				    if (!isset($this[$fieldName][$key]))
				    {
				      $this->addItem($fieldName, $key);
				    }
				  }
				  // mark items for deletion where they doesn't exist any more
				  foreach($this->embeddedForms[$fieldName] as $key=> $sfFormFieldSchema )
				  {
				  	if ($key != '_csrf_token' && !isset($taintedValues[$fieldName][$key])){ //it's not here anymore!
				  		unset($this->embeddedForms[$fieldName][$key]);
				  		unset($this->validatorSchema[$fieldName][$key]);
						unset($taintedValues[$fieldName][$key]);
						unset($taintedFiles[$fieldName][$key]);
				  		$this->scheduledForDeletion[$fieldName][$key] = $sfFormFieldSchema;  
				  	}
				  } 
			  }
			  else //There are no items. We must erase all off them!
			  {
 				  foreach($this->embeddedForms[$fieldName] as $key=> $sfFormFieldSchema )
				  {
				  	if($key != '_csrf_token')
				  	{
				  		$this->scheduledForDeletion[$fieldName][$key] = $sfFormFieldSchema;
				  	}  
				  } 
				  unset($this->embeddedForms[$fieldName]);
				  unset($this->validatorSchema[$fieldName]);
				  
			  }
			}
		}
  	}
	parent::bind($taintedValues, $taintedFiles);
  }
  
  protected function doSave($con = null)
  {
    $util = new Util();
    $self = $this->getObject();
    $class = $self->getTable()->getClassnameToReturn();
	$objDef = new objectDef($class);
	$user =  sfContext::getInstance()->getUser();
  	$filesToUpld = array();
	$itemsToSave = array();
	foreach($objDef->attributes as $fieldName => $att){
		if($att['show']){
			if($att['type']=='file' or $att['type']=='image'){
				 $file = true;
				 $validatorFile = $this->getValue($fieldName);
				 if(!isset($validatorFile) and $self->$fieldName != ''){
				 	//This means that the object has already a file and the user didn't send a new one..
				 	//We leave the old file name, and I don't make the upload
				 	unset($this[$fieldName]);
				 }else{
				 	$filesToUpld[]=$fieldName;
				 }
			}
		}
		if($att['type']=='BOList' and !sfConfig::get('app_autoforms_newitems', true)){
			$itemsToSave[$fieldName] = $user->getAttribute('itemsList'.$fieldName);
			if($this->getValue($fieldName)==''){
				unset($this[$fieldName.'_id']); //uset the field, so it doesn't give an error of invalid value when field type is numeric
			}
		}
	}
	/* doSave function original
	 * I've had to take out $this->saveEmbeddedForms($con); because it made two updates
	 * 
	 * */
    if (null === $con)
    {
      $con = $this->getConnection();
    }

    $this->updateObject();
    $this->getObject()->save($con);
	// embedded forms
    //$this->saveEmbeddedForms($con);
  	/*Fin doSave function original*/
	
	$self = $this->getObject();
	// Set Double reference for BOList Fields
	if(sfConfig::get('app_autoforms_newitems', true))
	{
		$save = false;
		foreach($objDef->attributes as $fieldName => $att)
		{
			if($att['type']=='BOList')
			{
				$fieldname2 = $fieldName . '_id';
				if(empty($self->$fieldname2))
				{
					$self->$fieldname2 = $self->id;
					$save = true;
				}
			}
		}
		if($save) $self->save();
	} 
	
	foreach($itemsToSave as $fieldName => $objects){
		if(is_array($objects)){
			$fieldName2 = $fieldName.'_id';
			$self->$fieldName2 = $self->id;
			Util::sendDebug('Owner: id ' . $self->id);
			foreach($objects as $key => $oneObject){
				$oneObject->owner_id = $self->id;
				//TODO If the new item has a ownerClass attribute save the class of the owner.
				/*
		$ownerClass = $this->getUser()->getAttribute('ownerClass');
    	$objTable = Doctrine::getTable($this->getClassName($request));
    	$relations = $objTable->getRelations();
		foreach ($relations as $name => $relation) {
			if($ownerClass==$relation->getClass()){
				$att_name = $relation->getLocal();
			}			
		}
		if(!isset($att_name)){
    		$form->setDefault('owner_id',$owner);
    		$hide = array();
		}else{
			$form->hideWidget($att_name);
			$hide=array($att_name);
			$form->setDefault($att_name,$owner);
		}

				 */
				
				$oneObject->save();
				Util::sendDebug('new object id' .$oneObject->id );
			}
		}else{
			Util::sendDebug("No es un array ");
		}
	}
	$itemsToDelete = $user->getAttribute('itemsToDelete');
	if(isset($itemsToDelete)){
		foreach($itemsToDelete as $key => $oneObject){
			$oneObject->delete();
		}
	}
	
    foreach($filesToUpld as $fieldName){
    	$file = $this->getValue($fieldName);
    	if	(!is_null($file)){
    		if($file->__toString()!=''){
		   		$savedFileName=$file->__toString();
		   		unlink($savedFileName);/*Symfony lo graba con un nombre al azar. Ademas, hay veces que la pifia con la extension. Lo borro y lo grabo de nuevo*/
	    		$validator = $this->getValidator($fieldName);
	    		$path = $validator->getOption('path');
	    		if(empty($path)){
	    			$path = sfConfig::get('sf_upload_dir');
	    		}
	    		$fileNamePattern = $objDef->attributes[$fieldName]['fisicalFileNamePattern'];
	   			if($fileNamePattern=='randomsha1'){
	   				$path_parts = pathinfo( $file->generateFilename());
					$filename = $path_parts['filename'];
	   			}elseif($fileNamePattern=='GUID'){
	   				$filename = $util->createGUID();
	   			}elseif($fileNamePattern=='originalFileName'){
	   				$path_parts = pathinfo($util->sanitize_filename($file->getOriginalName()));
					$filename = $path_parts['filename'];
	   			}elseif($fileNamePattern=='objectID'){
	   				$idField = $self->getTable()->getIdentifier();
	   				$filename = get_class($self).'_'.$self->$idField;
	   			}else{
	   				$filename = $util->createGUID();
	   				//$filename = sha1($file->getOriginalName());
	   			}
	           	$extension = $file->getOriginalExtension();
	   			$savedFileName = $file->save($path.DIRECTORY_SEPARATOR.$filename.$extension);
	   			$self->$fieldName = $savedFileName;
    		}
  		}
   	}
   	$files = $user->getAttribute('filesToUpload');
   	Util::sendDebug("Files en el save count: ".count($files), 2);
  	if(isset($files))
	{
		foreach($files as $key => $attach)
		{
			Util::sendDebug("Saving files: " . $key, 2);
			$attach->owner_id = $self->id;
			$attach->ownerclass = get_class($self);
			$attach->upload_file();
			$attach->save();
		}
	}
	$self->save();
	$this->afterCommit($self);
	/*Unregister items to save and to delete*/ 
  	foreach($objDef->attributes as $fieldName => $att){
		if($att['type']=='BOList'){
			$user->getAttributeHolder()->remove('itemsList'.$fieldName, 'namespace');
		}
	}
	if($user->hasAttribute('itemsToDelete')){
		$user->getAttributeHolder()->remove('itemsToDelete', 'namespace');
	}
  }	
  
  
    /**
   * Updates the values of the object with the cleaned up values.
   *
   * This function overides original in order to delete items deleted via embedded forms
   *
   * @param array $values An array of values
   */
  
  protected function doUpdateObject($values){
  	//$s = sfFormFieldSchema ;
  	//Util::sendDebug('Dentro del update object ' . $this->objectDef->className, 2);
  	
  	parent::doUpdateObject($values);
  	foreach($this->scheduledForDeletion as $fieldName => $item )
  	{
  		$classname = $this->objectDef->attributes[$fieldName]['relatedClass'];
  		foreach ($item as $key => $sfForm)
  		{
	  		$values = $sfForm->getValue();
	  		$id=$values['id'];
	  		$object = Doctrine::getTable($classname)->find($id);
	  		$object->delete();
	  		unset($values[$fieldName][$key]);  
        	unset($this->object[$fieldName][$key]);  
  		}	
  	}
  	//Util::sendDebug('Fin update object ' . $this->objectDef->className, 2);
  	
  }
  
  
 /* public function getJavaScripts()
  {


	$js = parent::getJavaScripts();
    $js[] = '/js/fancybox/fancybox-1.3.4.js';
    return $js;
  } */ 


  public function getStylesheets(){
  	$css = parent::getStylesheets();
    //$css['/css/default/forms.css'] = 'all';
    return $css;
  }
  
  public function regionalizeForm($classname = ''){
  	if($classname==''){
  		$classname = $this->getObject()->getTable()->getClassnameToReturn();
  	}
  	$this->hideWidget('region');
	$entityConfig = sfConfig::get('app_entity_config_'.$classname, false);
	if($entityConfig){
		if(isset($entityConfig['hide'])){
			foreach($entityConfig['hide'] as $attname){
				$this->hideWidget($attname);
			}	
		}
		if(isset($entityConfig['readOnly'])){
			foreach($entityConfig['readOnly'] as $attname){
				if(isset($this[$attname]))
				{
					$this->setReadOnly($attname);
				}
			}	
		}
		//Util::sendDebug("Warning : Regionalizing!");
		if(isset($entityConfig['filterCandidates'])){
			if($entityConfig['filterCandidates']){
				$sf_user = sfContext::getInstance()->getUser();
				$id_region = $sf_user->getAdminRegionId();
				if(!$id_region){
					$region = Doctrine::getTable('region')->findOneBy('code', $sf_user->getCodeRegion());
					$id_region = $region->id;
				}
				foreach($this->objectDef->attributes as $fieldName => $att){
					if($att['type']=='BO' or $att['type']=='CheckboxList')
					{
						$regConfMng = new regionalConfigMng($id_region);
						$relatedClass = $att['relatedClass'];
						$relatedObjDef = new objectDef($relatedClass);
						if($att['type']=='BO') $fieldName.='_id';
						if($att['type']=='CheckboxList') $fieldName.= '_list';
					}
					if($att['type']=='BO' and isset($this[$fieldName]))
					{ 
						
						$widget = $this->getWidget($fieldName);
						$q = $widget->getOption('query');
						if($q){
							if($relatedClass){
    							$q = $regConfMng->addRegionalFilterToView($q, $relatedObjDef);
    							$widget->setOption('query', $q);
    							//Util::sendDebug('Query B:');
							}else{
								//Util::sendDebug("ERROR : Not related class found");
							}
						}
					}
					elseif($att['type']=='CheckboxList' and isset($this[$fieldName]))
					{
						
						
						if(is_null($options)){
							$relatedTable = Doctrine::getTable($relatedClass);
							$id = $relatedTable->getIdentifier();	
							if($relatedObjDef->classExists){
									//$descriptor = ''; 
									$descriptor = $relatedObjDef->descriptor;
							}
							if($descriptor=='') $descriptor = 'id' ;
							//$filter = '';
							$addEmpty = false;
							$isnumeric = false;
							//$options = array('0'=>sfContext::getInstance()->getI18N()->__('Please select a value...'));
							$q=Doctrine_Query::create()
			    					->select('a.'.$id.' as id, a.'.$descriptor.'  as name')
								    ->from($relatedClass.' a') 
								    ->orderBy('a.'.$descriptor);
				 			if(!$filter==''){
								 if(substr($filter, 0,1) != '(')
								 {
								 	$filter = 'a.'.$filter;
								 }
								 $q->andWhere($filter);
							 }
						 	$q->setHydrationMode(Doctrine_Core::HYDRATE_ARRAY); 
			 					
							$q = $regConfMng->addRegionalFilterToView($q, $relatedObjDef);
							foreach($q->execute() as $opt){
						 		$options[$opt['id']]=$opt['name'];
						 	}
						}
						
						$this->widgetSchema[$fieldName] = new sfWidgetFormSelectCheckbox(
						array('choices'=>$options, 'formatter'=>array($this, 'radioListFormatter')));	//, 'multiple' => true,'expanded' => true)
							//$this->validatorSchema[$fieldName] =  new sfValidatorString(array('required' => false));
						$this->validatorSchema[$fieldName] = new sfValidatorDoctrineChoice(array('multiple' => true, 'model' => $relatedClass, 'required' => false));
					}
					
				}
			}
		}
	}	
  }

  /* 
   * This function is used to unset all BoList attributes in a form
   * Usefull to show items forms (BOList) that has themselfs other BoList Attributes
   *  
   */
  public function unsetBoListFields()
  {
  	foreach($this->objectDef->attributes as $fieldName => $att)
  	{
  		if($att['type']=='BOList')
  		{
  			unset($this[$fieldName]);
  		}	
  	}
  }
  
}
